﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Net;

namespace StellarMedical.Web
{
    [ServiceBehavior(
       InstanceContextMode = InstanceContextMode.Single,
       ConcurrencyMode = ConcurrencyMode.Single,
       AutomaticSessionShutdown = true)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class DuplexService : IDuplexService
    {

        private static RssChannelData ChannelData;

        private IDuplexClient _client = null;

        public DuplexService()
        {
            // create the duplex channel
        }

        public void InitiateDuplex()
        {
            _client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
        }

        public void BeginFetchData(string url)
        {

            ChannelData = new RssChannelData();

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            try
            {
                client.DownloadStringAsync(new Uri(url, UriKind.Absolute));
            }
            catch (Exception)
            {
                ChannelData.Title = "Couldn't load RSS data";
            }
        }

        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                ChannelData.Title = "Couldn't load RSS data";
                return;
            }

            XmlDocument rssChannel = new XmlDocument();
            rssChannel.LoadXml(e.Result);

            try
            {
                ChannelData.Title = rssChannel.GetElementsByTagName("description")[0].InnerText;

            }
            catch (Exception)
            {
                ChannelData.Title = "Couldn't load RSS data";
            }

            XmlNodeList items = rssChannel.GetElementsByTagName("item");

            ChannelData.Items = new List<RssItem>();

            foreach (XmlNode node in items)
            {
                RssItem tempItem = new RssItem();

                foreach (XmlNode n in node.ChildNodes)
                {
                    // prase the child nodes
                    switch (n.Name)
                    {
                        case "title":
                            tempItem.Title = n.InnerText;
                            break;

                        case "pubDate":
                            tempItem.Timestamp = n.InnerText;
                            break;

                        case "description":
                            tempItem.Body = n.InnerText;
                            break;

                        case "guid":
                            tempItem.Url = n.InnerText;
                            break;

                        case "link":
                            tempItem.Url = n.InnerText;
                            break;

                    }
                }

                ChannelData.Items.Add(tempItem);

            }

            // tell the client that the download is complete

            _client.BeginReceiveTitle(new RssInfo() { Title = ChannelData.Title }, EndReceiveTitle, _client);

        }

        private void EndReceiveItem(IAsyncResult result)
        {
            ChannelData.ItemIndex++;

            if (ChannelData.ItemIndex < ChannelData.Items.Count)
            {
                _client.BeginReceiveItem(ChannelData.Items[ChannelData.ItemIndex], EndReceiveItem, _client);
            }

        }

        private void EndReceiveTitle(IAsyncResult result)
        {
            // see if we need to send any items

            if (ChannelData.Items.Count > 0)
            {
                _client.BeginReceiveItem(ChannelData.Items[ChannelData.ItemIndex], EndReceiveItem, _client);
            }
        }



    }
}
